#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include "cmsis_os2.h"
#include "iot_errno.h"
#include "ohos_init.h"
#include "app_log.h"
#include "app_task.h"
#include "app_led.h"
#include "app_uart.h"
#include "app_adc.h"
#include "app_nfc.h"
#include "app_mpu6050.h"
#include "app_oled.h"
#include "app_pwm.h"
#include "app_env.h"
#include "app_wifi_udp.h"
#include "app_cloud.h"
#include "app_tcp_server.h"

static char *TAG = "app_main.c";

/* use code module start */
#define APP_MAIN_TASK 1
#define LED_STUDY_TASK 0
#define UART_STUDY_TASK 0
#define ADC_STUDY_TASK 0
#define NFC_STUDY_TASK 0
#define OLED_STUDY_TASK 1
#define MPU6050_STUDY_TASK 0
#define PWM_STUDY_TASK 0
#define ENV_STUDY_TASK 1
#define UDP_STUDY_TASK 0
#define TCP_SERVER_STUDY_TASK 0
#define CLOUD_STUDY_TASK 1
/* use code module end */

/* define app code start */
#define APP_TASK_STACK_SIZE (1024 * 8)
#define APP_TASK_PRIO 25
/* define app code end */

/* define led code start */
#define LED_TASK_STACK_SIZE (1024 * 4)
#define LED_TASK_PRIO 25
/* define led code end */

/* define uart code start */
#define UART_TASK_STACK_SIZE (1024 * 8)
#define UART_TASK_PRIO 25
/* define uart code end */

/* define ADC code start */
#define ADC_TASK_STACK_SIZE (1024 * 8)
#define ADC_TASK_PRIO 24
/* define ADC code end */

/* define nfc code start */
#define I2C_TASK_STACK_SIZE (1024 * 8)
#define I2C_TASK_PRIO 28
/* define nfc code end */

/* define oled code start */
#define OLED_TASK_STACK_SIZE (1024 * 8)
#define OLED_TASK_PRIO 23
/* define oled code end */

/* define mpu6050 code start */
#define MPU6050_TASK_STACK_SIZE (1024 * 4)
#define MPU6050_TASK_PRIO 25
/* define mpu6050 code end */

/* define pwm code start */
#define PWM_TASK_STACK_SIZE (1024 * 4)
#define PWM_TASK_PRIO 25
/* define pwm code end */

/* define env code start */
#define ENV_TASK_STACK_SIZE (1024 * 8)
#define ENV_TASK_PRIO 26
/* define env code end */

/* define udp code start */
#define UDP_TASK_STACK_SIZE (1024 * 10)
/* define udp code end */

/* define tcp server code start */
#define TCP_SERVER_TASK_STACK_SIZE (1024 * 10)
/* define tcp server code end */

/* define cloud code start */
#define CLOUD_TASK_STACK_SIZE (1024 * 10)
#define CLOUD_TASK_PRIO 25
#define SENSOR_TASK_STACK_SIZE (1024 * 8)
#define SENSOR_TASK_PRIO 26
/* define cloud code end */

static void app_main(void)
{
    /* create mutex */
    create_mutex();

    /* start task set osThreadAttr_t */
    osThreadAttr_t attr;

    attr.attr_bits = 0U;
    attr.cb_mem = NULL;
    attr.cb_size = 0U;
    attr.stack_mem = NULL;

    /* start create task */
#if APP_MAIN_TASK
    attr.name = "app_task";
    attr.priority = APP_TASK_PRIO;
    attr.stack_size = APP_TASK_STACK_SIZE;
    if (osThreadNew((osThreadFunc_t)app_task, NULL, &attr) == NULL)
    {
        MY_LOGI(TAG, "Failed to create AppTask!\n");
    }
    else
    {
        MY_LOGI(TAG, "Succeed to create AppTask!\n");
    }
#endif

#if LED_STUDY_TASK
    attr.name = "led_test_task";
    attr.priority = LED_TASK_PRIO;
    attr.stack_size = LED_TASK_STACK_SIZE;
    if (osThreadNew((osThreadFunc_t)led_test_task, NULL, &attr) == NULL)
    {
        MY_LOGI(TAG, "Failed to create LedTESTTask!\n");
    }
    else
    {
        MY_LOGI(TAG, "Succeed to create LedTESTTask!\n");
    }
#endif

#if UART_STUDY_TASK
    attr.name = "uart_test_task";
    attr.priority = UART_TASK_PRIO;
    attr.stack_size = UART_TASK_STACK_SIZE;
    if (osThreadNew((osThreadFunc_t)uart_test_task, NULL, &attr) == NULL)
    {
        MY_LOGI(TAG, "Failed to create UartTask!\n");
    }
    else
    {
        MY_LOGI(TAG, "Succeed to create UartTask!\n");
    }
#endif

#if ADC_STUDY_TASK
    attr.name = "gas_module_test_task";
    attr.priority = ADC_TASK_PRIO;
    attr.stack_size = ADC_TASK_STACK_SIZE;
    if (osThreadNew((osThreadFunc_t)gas_module_test_task, NULL, &attr) == NULL)
    {
        MY_LOGI(TAG, "Failed to create AdcTESTTask!\n");
    }
    else
    {
        MY_LOGI(TAG, "Succeed to create AdcTESTTask!\n");
    }
#endif

#if NFC_STUDY_TASK
    attr.name = "i2c_nfc_test_task";
    attr.priority = I2C_TASK_PRIO;
    attr.stack_size = I2C_TASK_STACK_SIZE;
    if (osThreadNew((osThreadFunc_t)i2c_nfc_test_task, NULL, &attr) == NULL)
    {
        MY_LOGI(TAG, "Failed to create I2cNFCTESTTask!\n");
    }
    else
    {
        MY_LOGI(TAG, "Succeed to create I2cNFCTESTTask!\n");
    }
#endif

#if OLED_STUDY_TASK
    attr.name = "oled_test_task";
    attr.priority = OLED_TASK_PRIO;
    attr.stack_size = OLED_TASK_STACK_SIZE;
    if (osThreadNew((osThreadFunc_t)oled_test_task, NULL, &attr) == NULL)
    {
        MY_LOGI(TAG, "Failed to create OLEDTESTTask!\n");
    }
    else
    {
        MY_LOGI(TAG, "Succeed to create OLEDTESTTask!\n");
    }
#endif

#if MPU6050_STUDY_TASK
    attr.name = "mpu6050_test_task";
    attr.priority = MPU6050_TASK_PRIO;
    attr.stack_size = MPU6050_TASK_STACK_SIZE;
    if (osThreadNew((osThreadFunc_t)mpu6050_test_task, NULL, &attr) == NULL)
    {
        MY_LOGI(TAG, "Failed to create MPU6050TESTTask!\n");
    }
    else
    {
        MY_LOGI(TAG, "Succeed to create MPU6050TESTTask!\n");
    }
#endif

#if PWM_STUDY_TASK
    attr.name = "pwm_test_task";
    attr.priority = PWM_TASK_PRIO;
    attr.stack_size = PWM_TASK_STACK_SIZE;
    if (osThreadNew((osThreadFunc_t)pwm_test_task, NULL, &attr) == NULL)
    {
        MY_LOGI(TAG, "Failed to create PWMTESTTask!\n");
    }
    else
    {
        MY_LOGI(TAG, "Succeed to create PWMTESTTask!\n");
    }
#endif

#if ENV_STUDY_TASK
    attr.name = "env_task";
    attr.priority = ENV_TASK_PRIO;
    attr.stack_size = ENV_TASK_STACK_SIZE;
    if (osThreadNew((osThreadFunc_t)env_task, NULL, &attr) == NULL)
    {
        MY_LOGI(TAG, "Failed to create EnvTask!\n");
    }
    else
    {
        MY_LOGI(TAG, "Succeed to create EnvTask!\n");
    }
#endif

#if UDP_STUDY_TASK
    attr.name = "UDPClientTask";
    attr.stack_size = UDP_TASK_STACK_SIZE;
    attr.priority = osPriorityNormal;
    if (osThreadNew((osThreadFunc_t)UDPClientTask, NULL, &attr) == NULL)
    {
        MY_LOGI(TAG, "[UDPClientDemo] Failed to create UDPClientTask!\n");
    }
    else
    {
        MY_LOGI(TAG, "[UDPClientDemo] Succeed to create UDPClientTask!\n");
    }
#endif

#if TCP_SERVER_STUDY_TASK
    attr.name = "TCPServerTask";
    attr.stack_size = TCP_SERVER_TASK_STACK_SIZE;
    attr.priority = osPriorityNormal;
    if (osThreadNew((osThreadFunc_t)TCPServerTask, NULL, &attr) == NULL)
    {
        MY_LOGI(TAG, "[TCPServerDemo] Failed to create TCPServerTask!\n");
    }
    else
    {
        MY_LOGI(TAG, "[TCPServerDemo] Succeed to create TCPServerTask!\n");
    }
#endif

#if CLOUD_STUDY_TASK
    attr.name = "CloudMainTaskEntry";
    attr.stack_size = CLOUD_TASK_STACK_SIZE;
    attr.priority = CLOUD_TASK_PRIO;
    if (osThreadNew((osThreadFunc_t)CloudMainTaskEntry, NULL, &attr) == NULL)
    {
        MY_LOGI(TAG, "Faifan to create CloudMainTaskEntry!\n");
    }
    else
    {
        MY_LOGI(TAG, "Succeed to create CloudMainTaskEntry!\n");
    }

    attr.stack_size = SENSOR_TASK_STACK_SIZE;
    attr.priority = SENSOR_TASK_PRIO;
    attr.name = "SensorTaskEntry";
    if (osThreadNew((osThreadFunc_t)SensorTaskEntry, NULL, &attr) == NULL)
    {
        MY_LOGI(TAG, "Faifan to create SensorTaskEntry!\n");
    }
    else
    {
        MY_LOGI(TAG, "Succeed to create SensorTaskEntry!\n");
    }
#endif
}

APP_FEATURE_INIT(app_main);
